/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package desarrollosoft.ghce.servicio.implementaciones;

import desarrollosoft.ghce.dao.interfaces.IBajaLogicaPacienteDAO;
import desarrollosoft.ghce.dao.interfaces.IPacienteDAO;
import desarrollosoft.ghce.dao.interfaces.ISexoDAO;
import desarrollosoft.ghce.dao.interfaces.ITipoDocumentoDAO;
import desarrollosoft.ghce.entidades.BajaLogicaPaciente;
import desarrollosoft.ghce.entidades.Paciente;
import desarrollosoft.ghce.entidades.Sexo;
import desarrollosoft.ghce.entidades.TipoDocumento;
import desarrollosoft.ghce.servicio.interfaces.IServicioPacientes;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author ariel
 */
@Service("servicioPacientes")
public class ServicioPacientes implements IServicioPacientes {

    @Autowired
    @Qualifier("tipoDocumentoDAO")
    private ITipoDocumentoDAO tipoDocumentoDAO;
    
    @Autowired
    @Qualifier("pacienteDAO")
    private IPacienteDAO pacienteDAO;
    
    @Autowired
    @Qualifier("sexoDAO")
    private ISexoDAO sexoDAO;
    
    @Autowired
    @Qualifier("bajaLogicaPacienteDAO")
    private IBajaLogicaPacienteDAO bajaLogicaPacienteDAO;
    
    // investigar si poner o no synchronized
    @Override
    @Transactional(readOnly = true)
    public List<Paciente> buscarPacienteActivo(String dato, String tipoDato) throws Exception {
        List<Paciente> listaRetorno;
        String tipoDatoMayusculas = tipoDato.toUpperCase();
        switch (tipoDatoMayusculas) {
            case "IDENTIFICACION":
                listaRetorno = pacienteDAO.buscarActivosPorIdentificacion(dato);
                break;
            case "APELLIDO":
                listaRetorno = pacienteDAO.buscarActivosPorApellido(dato);
                break;
            default:
                throw new Exception("tipo de dato no encontrado en el servicio");
        }
        return listaRetorno;
    }

    @Override
    @Transactional
    public void crearPaciente(Paciente paciente) throws Exception {
        pacienteDAO.crearPaciente(paciente);
    }

    @Override
    @Transactional
    public void modificarPaciente(Paciente paciente) throws Exception {
        pacienteDAO.modificarPaciente(paciente);
    }

    @Override
    @Transactional(readOnly = true)
    public List<TipoDocumento> obtenerTiposDocumento() {
        return tipoDocumentoDAO.obtenerTodosTipoDocumento();
    }

    @Override
    @Transactional(readOnly = true)
    public List<Sexo> obtenerTodosSexo() {
        return sexoDAO.obtenerTodosSexo();
    }

    @Override
    public List<String> listaTiposDatosBuscables() {
        List<String> lista = new ArrayList<>();
        lista.add("Apellido");
        lista.add("Identificacion");
        return lista;
    }

    @Override
    @Transactional
    public void eliminarLogicaPaciente(Paciente paciente, String causas, Date fechaSuceso) throws Exception {
        if (paciente == null || causas == null || fechaSuceso == null) {
            throw new Exception("ServicioPacientes.eliminarLogicaPaciente: ninguno de los argumentos puede ser null");
        }
        if ( paciente.getBajaLogicaPaciente() != null ) {
            throw new Exception("ServicioPacientes.eliminarLogicaPaciente: el paciente ya esta dado de baja");
        }
        
        /*
            Si la fecha del suceso es antes que la fecha de nacimiento de paciente
        */
        if (fechaSuceso.before(paciente.getFechaNacimiento())) {
            throw new Exception("La fecha del suceso no puede ser anterior a la fecha de nacimiento del paciente");
        }
        
        BajaLogicaPaciente bajaLogicaPaciente = new BajaLogicaPaciente();
        bajaLogicaPaciente.setCausas(causas);
        bajaLogicaPaciente.setFechaSuceso(fechaSuceso);
        
        bajaLogicaPacienteDAO.crearBajaLogica(bajaLogicaPaciente); // creo y persisto baja logica
        paciente.setBajaLogicaPaciente(bajaLogicaPaciente); // seteo baja a paciente
        pacienteDAO.modificarPaciente(paciente); // persisto la modificacion en el paciente
    }

    @Override
    @Transactional
    public void reactivarPaciente(Paciente paciente) throws Exception {
        if (paciente.getBajaLogicaPaciente() == null) {
            throw new Exception("El paciente que intenta reactivar, no esta dado de baja");
        }
        BajaLogicaPaciente bajaLogica = paciente.getBajaLogicaPaciente();
        paciente.setBajaLogicaPaciente(null);
        pacienteDAO.modificarPaciente(paciente);
        bajaLogicaPacienteDAO.eliminarBajaLogica(bajaLogica);
    }
    
}
